/**
* Author:LSP
* Date:2020-12-16
*/

// 小组件配置
const widgetConfigs = {
    // 预览尺寸：medium、large
    preview: "large",
    // 疫情新闻api
    covidNewsApi: "https://api.inews.qq.com/newsqa/v1/automation/modules/list?modules=FAutoNewsArticleList",
    // 疫情新闻缓存key
    covidNewsCacheKey: "covid-news",
    // 疫情数据api
    covidDataApi: `https://c.m.163.com/ug/api/wuhan/app/data/list-total?t=${new Date().getTime()}`,
    // 疫情数据缓存key
    covidDataCacheKey: `covid-data`,

    // 中组件
    medium: {
        // 背景图
        bgImgUrl: "https://mat1.gtimg.com/news/feiyanarea/head_bg_new.png",
        // logo图
        logoImgUrl: "https://s3.ax1x.com/2020/12/06/DOxwSH.png",
        // 背景图缓存key
        bgImgCacheKey: "covid-bg-medium",
        // logo缓存key
        logoImgCacheKey: "covid-logo",
        // 背景前景色
        bgImgShadowColor: new Color("000000", 0),
        // 横向文字间距
        horizontalFontMargin: 6,
        // 大标题底下间距
        headTitleBottomMaigin: 4,
        // logo尺寸
        logoImgSize: new Size(25, 25),
        // 大标题
        headTitleText: "新冠肺炎疫情最新进展",
        // 大标题字体
        headTitleFont: Font.systemFont(15),
        // 大标题颜色，后面的数字表示透明度
        headTitleColor: new Color("FFFFFF", 0.7),
        // 新闻标题序号字体
        titleNumFont: Font.italicSystemFont(14),
        // 新闻标题序号颜色，后面的数字表示透明度
        titleNumColor: new Color("E44A3D", 1),
        // 新闻标题字体
        titleFont: Font.systemFont(13),
        // 新闻标题颜色，后面的数字表示透明度
        titleColor: new Color("FFFFFF", 0.7),
        // 新闻时间字体
        newsTimeFont: Font.italicSystemFont(13),
        // 新闻时间颜色，后面的数字表示透明度
        newsTimeColor: new Color("FFFFFF", 0.6),
    },

    // 大组件
    large: {
        // 大标题
        headTitleText: "国内疫情",
        // 背景图
        bgImgUrl: "https://s3.ax1x.com/2020/12/06/DjkS5n.png",
        // 疫情数据url
        covidUrl: "https://wp.m.163.com/163/page/news/virus_report/index.html?_nw_=1&_anw_=1",
        // 背景图缓存key
        bgImgCacheKey: "covid-bg-big",
        // 横向文字间距
        horizontalFontMargin: 6,
        // 大标题底下间距
        headTitleBottomMaigin: 4,
        // 大标题字体
        headTitleFont: Font.boldSystemFont(14),
        // 大标题颜色，后面的数字表示透明度
        headTitleColor: new Color("000000", 0.7),
        // 背景前景色
        bgImgShadowColor: new Color("FFFFFF", 0.7),
        // 新闻标题序号字体
        titleNumFont: Font.italicSystemFont(14),
        // 新闻标题序号颜色，后面的数字表示透明度
        titleNumColor: new Color("E44A3D", 1),
        // 疫情标题字体大小
        covidHeadFont: Font.systemFont(12),
        // 疫情数字字体大小
        covidDataFont: Font.boldSystemFont(18),
        // 疫情新增字体大小
        covidIncreaseFont: Font.systemFont(11),
        // 疫情stack背景色
        covidStackBgColor: new Color("FFFFFF", 0.5),
        // 消息标题
        newsTitleText: "疫情最新进展",
        // 新闻标题字体
        titleFont: Font.systemFont(13),
        // 新闻标题颜色，后面的数字表示透明度
        titleColor: new Color("555555", 1),
        // 新闻时间字体
        newsTimeFont: Font.italicSystemFont(13),
        // 新闻时间颜色，后面的数字表示透明度
        newsTimeColor: new Color("888888", 1),
    },
}
//------------------------------


//------------------------------
/**
* 绘制图片阴影浮层
* @param {Image} img 图片
* @param {Color} shadowColor 阴影颜色
* @return {Image}
*/
async function loadShadowColor2Image(img, shadowColor) {
    let drawContext = new DrawContext()
    drawContext.size = img.size
    // 把图片画上去
    drawContext.drawImageInRect(img, new Rect(0, 0, img.size['width'], img.size['height']))
    // 填充蒙版颜色
    drawContext.setFillColor(shadowColor)
    // 填充
    drawContext.fillRect(new Rect(0, 0, img.size['width'], img.size['height']))
    return await drawContext.getImage()
}

/**
* Http Get 请求接口
* @param {string} url 请求的url
* @param {string} cacheKey 缓存key
* @param {bool} json 返回数据是否为json，默认true
* @return {string | json | null}
*/
async function httpGet(url, cacheKey, json = true) {
    let data = null
    try {
        let req = new Request(url)
        data = await (json ? req.loadJSON() : req.loadString())
    } catch (e) {
        console.error(`httpGet请求失败：${e}`)
    }
    // 判断数据是否为空（加载失败）
    if (!data && Keychain.contains(cacheKey)) {
        // 判断是否有缓存
        let cache = Keychain.get(cacheKey)
        return json ? JSON.parse(cache) : cache
    }
    // 存储缓存
    Keychain.set(cacheKey, json ? JSON.stringify(data) : data)
    return data
}

/**
* 获取图片
* @param {string} url 图片链接
* @param {string} cacheKey 缓存的key
* @param {bool} useCache 是否使用缓存
* @return {Image}
*/
async function getImageByUrl(url, cacheKey, useCache = true) {
    const cacheFile = FileManager.local().joinPath(FileManager.local().temporaryDirectory(), cacheKey)
    const exists = FileManager.local().fileExists(cacheFile)
    // 判断是否有缓存
    if (useCache && exists) {
        return Image.fromFile(cacheFile)
    }
    try {
        const req = new Request(url)
        const img = await req.loadImage()
        // 存储到缓存
        FileManager.local().writeImage(cacheFile, img)
        return img
    } catch (e) {
        console.error(`图片加载失败：${e}`)
        if (exists) {
            return Image.fromFile(cacheFile)
        }
        // 没有缓存+失败情况下，返回黑色背景
        let ctx = new DrawContext()
        ctx.size = new Size(100, 100)
        ctx.setFillColor(Color.black())
        ctx.fillRect(new Rect(0, 0, 100, 100))
        return await ctx.getImage()
    }
}
//------------------------------


//------------------------------
// 渲染中组件
async function renderMedium(widget) {
    widget.setPadding(10, 12, 0, 0)
    const headTitleStack = widget.addStack()
    headTitleStack.layoutHorizontally()
    headTitleStack.centerAlignContent()

    const logoImg = await getImageByUrl(widgetConfigs.medium.logoImgUrl, widgetConfigs.medium.logoImgCacheKey)
    const widgetLogoImg = headTitleStack.addImage(logoImg)
    widgetLogoImg.imageSize = widgetConfigs.medium.logoImgSize

    headTitleStack.addSpacer(widgetConfigs.medium.horizontalFontMargin)
    const widgetTitleText = headTitleStack.addText(widgetConfigs.medium.headTitleText)
    widgetTitleText.font = widgetConfigs.medium.headTitleFont
    widgetTitleText.textColor = widgetConfigs.medium.headTitleColor

    widget.addSpacer(widgetConfigs.medium.headTitleBottomMaigin)
    let newsArr = await getCovidNew()
    newsArr = newsArr.slice(0, 4)
    let index = 0
    for (let news of newsArr) {
        index = index + 1
        const titleStack = widget.addStack()
        titleStack.url = news.url
        titleStack.layoutHorizontally()

        const titleNumWidgetText = titleStack.addText(`${index}`)
        titleNumWidgetText.font = widgetConfigs.medium.titleNumFont
        titleNumWidgetText.textColor = widgetConfigs.medium.titleNumColor

        titleStack.addSpacer(widgetConfigs.medium.horizontalFontMargin)
        const titleWidgetText = titleStack.addText(`${news.title}`)
        titleWidgetText.font = widgetConfigs.medium.titleFont
        titleWidgetText.textColor = widgetConfigs.medium.titleColor

        titleStack.addSpacer(widgetConfigs.medium.horizontalFontMargin)
        const timeWidgetText = titleStack.addText(`${news.publish_time.slice(5, 10)}`)
        timeWidgetText.font = widgetConfigs.medium.newsTimeFont
        timeWidgetText.textColor = widgetConfigs.medium.newsTimeColor

        titleStack.addSpacer()
        widget.addSpacer()
    }

    widget.addSpacer()

    //------------------------------
    // 获取背景图+设置背景图
    let widgetBgImg = await getImageByUrl(widgetConfigs.medium.bgImgUrl, widgetConfigs.medium.bgImgCacheKey)
    widgetBgImg = await loadShadowColor2Image(widgetBgImg, widgetConfigs.medium.bgImgShadowColor)
    widget.backgroundImage = widgetBgImg
    //------------------------------
}
//------------------------------


//------------------------------
// 渲染大组件
async function renderLarge(widget) {
    widget.setPadding(0, 0, 0, 0)

    widget.addSpacer()
    // 标题
    const headTitleStack = widget.addStack()
    headTitleStack.layoutHorizontally()
    headTitleStack.addSpacer()
    headTitleStack.centerAlignContent()
    //
    headTitleStack.addSpacer(widgetConfigs.large.horizontalFontMargin)
    let widgetTitleText = headTitleStack.addText(widgetConfigs.large.headTitleText)
    widgetTitleText.font = widgetConfigs.large.headTitleFont
    widgetTitleText.textColor = widgetConfigs.large.headTitleColor
    headTitleStack.addSpacer()
    //
    widget.addSpacer(widgetConfigs.large.headTitleBottomMaigin)
    const dataInfoStack = widget.addStack()
    dataInfoStack.url = widgetConfigs.large.covidUrl
    dataInfoStack.layoutVertically()
    dataInfoStack.backgroundColor = widgetConfigs.large.covidStackBgColor
    dataInfoStack.addSpacer(6)
    // 第一个
    const dataOneStack = dataInfoStack.addStack()
    dataOneStack.layoutHorizontally()
    // 第二个
    dataInfoStack.addSpacer(10)
    const dataTwoStack = dataInfoStack.addStack()
    dataTwoStack.layoutHorizontally()
    dataInfoStack.addSpacer(6)

    // 添加数据stack
    function addDataStack(parentStack, title, titleColor, dataNum, dataNumColor, increaseNum, increaseNumColor) {
        // 新增的字体颜色
        const increaseTextColor = new Color("999999", 1)
        // 标题
        const dataStack = parentStack.addStack()
        dataStack.layoutVertically()
        // 标题
        let infoStack = dataStack.addStack()
        infoStack.layoutHorizontally()
        infoStack.addSpacer()
        let widgetInputText = infoStack.addText(`${title}`)
        widgetInputText.font = widgetConfigs.large.covidHeadFont
        widgetInputText.textColor = titleColor
        infoStack.addSpacer()
        dataStack.addSpacer(2)
        // 数据
        infoStack = dataStack.addStack()
        infoStack.layoutHorizontally()
        infoStack.addSpacer()
        widgetInputText = infoStack.addText(`${dataNum}`)
        widgetInputText.font = widgetConfigs.large.covidDataFont
        widgetInputText.textColor = dataNumColor
        infoStack.addSpacer()
        dataStack.addSpacer(2)
        // 昨日比较
        infoStack = dataStack.addStack()
        infoStack.layoutHorizontally()
        infoStack.addSpacer()
        widgetInputText = infoStack.addText("较昨日")
        widgetInputText.font = widgetConfigs.large.covidIncreaseFont
        widgetInputText.textColor = increaseTextColor
        // 比昨日新增数据
        widgetInputText = infoStack.addText(`+${increaseNum}`)
        widgetInputText.font = widgetConfigs.large.covidIncreaseFont
        widgetInputText.textColor = increaseNumColor
        infoStack.addSpacer()
    }

    // 疫情数据
    const covidData = await getCovidData(covidProvinceName, covidAreaName)
    /**
    * 国内
    */
    const chinaCovidData = covidData.chinaCovidData
    // total
    const chinaTotal = chinaCovidData.total
    // today 
    const chinaToday = chinaCovidData.today
    // extData 
    const chinaExtData = chinaCovidData.extData

    // 第一行
    // 境外输入
    let input = chinaTotal.input
    if (input == undefined || input == null) {
        input = 0
    }
    let inputIncrease = chinaToday.input
    if (inputIncrease == undefined || inputIncrease == null) {
        inputIncrease = 0
    }
    addDataStack(
        dataOneStack,

        "境外输入",
        new Color("333333", 1),

        `${input}`,
        new Color("ffa352", 1),

        `${inputIncrease}`,
        new Color("ffa352", 1)
    )
    // 无症状感染者
    let noSymptom = chinaExtData.noSymptom
    if (noSymptom == undefined || noSymptom == null) {
        noSymptom = 0
    }
    let noSymptomIncrease = chinaExtData.incrNoSymptom
    if (noSymptomIncrease == undefined || noSymptomIncrease == null) {
        noSymptomIncrease = 0
    }
    addDataStack(
        dataOneStack,

        "无症状感染者",
        new Color("333333", 1),

        `${noSymptom}`,
        new Color("791618", 1),

        `${noSymptomIncrease}`,
        new Color("791618", 1)
    )
    // 现有确诊
    let totalHeal = chinaTotal.confirm - chinaTotal.dead - chinaTotal.heal
    if (totalHeal == undefined || totalHeal == null) {
        totalHeal = 0
    }
    totalHeal = Math.max(0, totalHeal)
    let storeConfirm = chinaToday.storeConfirm
    if (storeConfirm == undefined || storeConfirm == null) {
        storeConfirm = 0
    }
    addDataStack(
        dataOneStack,

        "现有确诊",
        new Color("333333", 1),

        `${totalHeal}`,
        new Color("e44a3d", 1),

        `${storeConfirm}`,
        new Color("e44a3d", 1)
    )
    // 第二行
    // 累计确诊
    let confirm = chinaTotal.confirm
    if (confirm == undefined || confirm == null) {
        confirm = 0
    }
    let confirmIncrease = chinaToday.confirm
    if (confirmIncrease == undefined || confirmIncrease == null) {
        confirmIncrease = 0
    }
    addDataStack(
        dataTwoStack,

        "累计确诊",
        new Color("333333", 1),

        `${confirm}`,
        new Color("a31d13", 1),

        `${confirmIncrease}`,
        new Color("a31d13", 1)
    )
    // 累计死亡
    let dead = chinaTotal.dead
    if (dead == undefined || dead == null) {
        dead = 0
    }
    let deadIncrease = chinaToday.dead
    log(deadIncrease)
    if (deadIncrease == undefined || deadIncrease == null) {
        deadIncrease = 0
    }
    addDataStack(
        dataTwoStack,

        "累计死亡",
        new Color("333333", 1),

        `${dead}`,
        new Color("333333", 1),

        `${deadIncrease}`,
        new Color("333333", 1)
    )
    // 累计治愈 
    let heal = chinaTotal.heal
    if (heal == undefined || heal == null) {
        heal = 0
    }
    let healIncrease = chinaToday.heal
    if (healIncrease == undefined || healIncrease == null) {
        healIncrease = 0
    }
    addDataStack(
        dataTwoStack,

        "累计治愈",
        new Color("333333", 1),

        `${heal}`,
        new Color("34aa70", 1),

        `${healIncrease}`,
        new Color("34aa70", 1)
    )


    /**
    * 具体地区疫情
    */
    const areaCovidData = covidData.areaCovidData
    // total
    const areaTotal = areaCovidData.total
    // today 
    const areaToday = areaCovidData.today
    // extData 
    const areaExtData = areaCovidData.extData
    widget.addSpacer(4)
    const secondHeadTitleStack = widget.addStack()
    secondHeadTitleStack.addSpacer()
    secondHeadTitleStack.layoutHorizontally()
    secondHeadTitleStack.centerAlignContent()
    //
    secondHeadTitleStack.addSpacer(widgetConfigs.large.horizontalFontMargin)
    // 具体地区疫情
    widgetTitleText = secondHeadTitleStack.addText(`${covidAreaName}疫情`)
    widgetTitleText.font = widgetConfigs.large.headTitleFont
    widgetTitleText.textColor = widgetConfigs.large.headTitleColor
    secondHeadTitleStack.addSpacer()
    // 数据
    widget.addSpacer(4)
    const covidAreaInfoStack = widget.addStack()
    covidAreaInfoStack.layoutVertically()
    covidAreaInfoStack.backgroundColor = widgetConfigs.large.covidStackBgColor
    covidAreaInfoStack.url = widgetConfigs.large.covidUrl
    covidAreaInfoStack.addSpacer(6)
    const dataAreaStack = covidAreaInfoStack.addStack()
    dataAreaStack.layoutHorizontally()
    covidAreaInfoStack.addSpacer(6)

    // 第一行
    // 现有确诊
    storeConfirm = areaTotal.confirm - areaTotal.dead - areaTotal.heal
    if (storeConfirm == undefined || storeConfirm == null) {
        storeConfirm = 0
    }
    storeConfirm = Math.max(0, storeConfirm)
    let storeConfirmIncrease = areaToday.storeConfirm
    if (storeConfirmIncrease == undefined || storeConfirmIncrease == null) {
        storeConfirmIncrease = 0
    }
    addDataStack(
        dataAreaStack,

        "现有确诊",
        new Color("333333", 1),

        `${storeConfirm}`,
        new Color("f23a3b", 1),

        `${storeConfirmIncrease}`,
        new Color("f23a3b", 1)
    )
    // 累计确诊
    confirm = areaTotal.confirm
    if (confirm == undefined || confirm == null) {
        confirm = 0
    }
    confirmIncrease = areaToday.confirm
    if (confirmIncrease == undefined || confirm == null) {
        confirmIncrease = 0
    }
    addDataStack(
        dataAreaStack,

        "累计确诊",
        new Color("333333", 1),

        `${confirm}`,
        new Color("cc1e1e", 1),

        `${confirmIncrease}`,
        new Color("cc1e1e", 1)
    )
    // 累计治愈
    heal = areaTotal.heal
    if (heal == undefined || heal == null) {
        heal = 0
    }
    healIncrease = areaToday.heal
    if (healIncrease == undefined || confirm == null) {
        healIncrease = 0
    }
    addDataStack(
        dataAreaStack,

        "累计治愈",
        new Color("333333", 1),

        `${heal}`,
        new Color("178b50", 1),

        `${healIncrease}`,
        new Color("178b50", 1)
    )
    // 累计死亡
    dead = areaTotal.dead
    if (dead == undefined || dead == null) {
        dead = 0
    }
    deadIncrease = areaToday.dead
    if (deadIncrease == undefined || confirm == null) {
        deadIncrease = 0
    }
    addDataStack(
        dataAreaStack,

        "累计死亡",
        new Color("333333", 1),

        `${dead}`,
        new Color("4e5a65", 1),

        `${deadIncrease}`,
        new Color("4e5a65", 1)
    )


    /**
    * 疫情最新进展
    */
    widget.addSpacer(4)
    const newsTitleStack = widget.addStack()
    newsTitleStack.addSpacer()
    newsTitleStack.layoutHorizontally()
    newsTitleStack.centerAlignContent()
    //
    newsTitleStack.addSpacer(widgetConfigs.large.horizontalFontMargin)
    // 标题
    widgetTitleText = newsTitleStack.addText(`🦠 ${widgetConfigs.large.newsTitleText}`)
    widgetTitleText.font = widgetConfigs.large.headTitleFont
    widgetTitleText.textColor = widgetConfigs.large.headTitleColor
    newsTitleStack.addSpacer()
    // 数据
    widget.addSpacer(4)
    const newsInfoStack = widget.addStack()
    newsInfoStack.layoutVertically()
    newsInfoStack.backgroundColor = widgetConfigs.large.covidStackBgColor
    newsInfoStack.addSpacer(6)
    const newsStack = newsInfoStack.addStack()
    newsStack.layoutVertically()
    newsInfoStack.addSpacer(6)
    let newsArr = await getCovidNew()
    const count = 2
    newsArr = newsArr.slice(0, count)
    let index = 0
    for (let news of newsArr) {
        index = index + 1
        const titleStack = newsStack.addStack()
        titleStack.url = news.url
        titleStack.layoutHorizontally()

        titleStack.addSpacer(8)
        const titleNumWidgetText = titleStack.addText(`${index}`)
        titleNumWidgetText.font = widgetConfigs.large.titleNumFont
        titleNumWidgetText.textColor = widgetConfigs.large.titleNumColor

        titleStack.addSpacer(widgetConfigs.large.horizontalFontMargin)
        const titleWidgetText = titleStack.addText(`${news.title}`)
        titleWidgetText.font = widgetConfigs.large.titleFont
        titleWidgetText.textColor = widgetConfigs.large.titleColor

        titleStack.addSpacer(widgetConfigs.large.horizontalFontMargin)
        const timeWidgetText = titleStack.addText(`${news.publish_time.slice(5, 10)}`)
        timeWidgetText.font = widgetConfigs.large.newsTimeFont
        timeWidgetText.textColor = widgetConfigs.large.newsTimeColor

        titleStack.addSpacer()
        if (count != index) {
            newsStack.addSpacer(6)
        }
    }

    //------------------------------
    // 获取背景图+设置背景图
    let widgetBgImg = await getImageByUrl(widgetConfigs.large.bgImgUrl, widgetConfigs.large.bgImgCacheKey, true)
    widgetBgImg = await loadShadowColor2Image(widgetBgImg, widgetConfigs.large.bgImgShadowColor)
    widget.backgroundImage = widgetBgImg
    //------------------------------
    widget.addSpacer()
}
//------------------------------


//------------------------------
/**
* 获取最新资讯
*/
async function getCovidNew() {
    const response = await httpGet(widgetConfigs.covidNewsApi, widgetConfigs.covidNewsCacheKey)
    return response.data.FAutoNewsArticleList
}

/**
* 获取疫情数据
*/
async function getCovidData(provinceName, areaName) {
    const response = await httpGet(widgetConfigs.covidDataApi, widgetConfigs.covidDataCacheKey)
    const data = response.data
    // 国内疫情数据
    const chinaCovidData = data.chinaTotal
    // 查找指定输入地区疫情数据
    let areaCovidData = undefined
    for (let area of data.areaTree) {
        if (area.name == "中国") {
            let children = area.children
            for (let city of children) {
                if (city.name == provinceName) {
                    children = city.children
                    if (children.length == 1) {
                        areaCovidData = children[0]
                        break
                    } else {
                        for (let area of children) {
                            if (area.name == areaName) {
                                areaCovidData = area
                                break
                            }
                        }
                    }
                    break
                }
            }
            break
        }
    }

    return { chinaCovidData: chinaCovidData, areaCovidData: areaCovidData }
}
//------------------------------


//------------------------------
const widget = new ListWidget()
// 获取外部输入的参数
let widgetInputRAW = args.widgetParameter
try {
    widgetInputRAW.toString()
} catch (e) {
    widgetInputRAW = "广东,广州"
}
// 指定疫情地区
const covidNameArr = widgetInputRAW.toString().replace("，", ",").split(",")
const covidProvinceName = covidNameArr[0]
const covidAreaName = covidNameArr[1]
//------------------------------


//------------------------------
const widgetFamily = config.widgetFamily
log(`小组件大小：${widgetFamily}`)
if (widgetFamily == "medium") {
    await renderMedium(widget)
} else if (widgetFamily == "large") {
    await renderLarge(widget)
} else {
    // 完成进行预览
    if (widgetConfigs.preview == "medium") {
        await renderMedium(widget)
        widget.presentMedium()
    } else {
        await renderLarge(widget)
        widget.presentLarge()
    }
}

Script.setWidget(widget)
Script.complete()
    //------------------------------